package ac.github.os.internal.core.condition.impl.entity.interact

import ac.github.os.internal.core.condition.Condition
import ac.github.os.internal.core.config.StringConfig
import ac.github.os.internal.core.config.get
import ac.github.os.internal.core.holder.entity.InteractHolder
import ac.github.os.internal.session.Session
import org.bukkit.Location
import taboolib.common.platform.Awake

abstract class InteractCondition(
    val name: String
) : Condition {

    override fun doScreen(session: Session, config: StringConfig): Boolean {
        val holder = session.holder
        if (holder is InteractHolder) {
            return this.run(session, config, holder)
        }
        return false
    }

    abstract fun run(session: Session, config: StringConfig, holder: InteractHolder): Boolean

    override val namespace: String
        get() = "interact:$name"

    fun StringConfig.value(def: String? = null): String? = get("val", def, single = true)

}

@Awake
class InteractHand : InteractCondition("hand") {
    override fun run(session: Session, config: StringConfig, holder: InteractHolder): Boolean {
        return config.value("HAND") == holder.event.hand?.name
    }
}

@Awake
class InteractAction : InteractCondition("action") {
    override fun run(session: Session, config: StringConfig, holder: InteractHolder): Boolean {
        return holder.event.action.name == config.value()
    }
}

@Awake
class InteractClickBlock : InteractCondition("click:block") {
    override fun run(session: Session, config: StringConfig, holder: InteractHolder): Boolean {
        val clickedBlock = holder.event.clickedBlock ?: return false
        val type = config.get<String>("type") ?: return false
        val location = config.get("loc", clickedBlock.location)!!
        val range = config.get("range", 1.0)!!
        return type == clickedBlock.type.name && location.distance(clickedBlock.location) <= range
    }
}